package tr.edu.boun.phys.springmassmodel.audio;

public class WaveTable {
	
	private int[] table;
	private int tableLength;
	private double phase;
	private double frequency;
	private static final int SAMPLE_RATE = 44100;
	
	public WaveTable() {
		phase = 1.0;
		frequency = 55.0;
		tableLength = 128;
		table = new int[tableLength+3];
		//addPartial(1);
	}
	
	public WaveTable(int nSamples) {
		this.tableLength = nSamples;
		phase = 1.0;
		frequency = 110.0;
		tableLength = 128;
		table = new int[tableLength+3];
		//addPartial(1);
	}
	
	/*public int sampleAt(int index) {
		return table[index+1];
	}*/
	
	public int[] calculateSamples(int N) {
		int[] samples = new int[N];
		
		for(int i=0; i<N; i++) {
			//System.out.println(phase);
			samples[i] = getSample(phase);
			//System.out.println(samples[i]);
			
			phase += frequency * tableLength / SAMPLE_RATE;
			if(phase >= tableLength+1) phase -= tableLength;
		}
		return samples;
	}
	
	private int getSample(double index) {
		int n = (int)index;
		int value = table[n];
		double f = index - n;
		
		double y = (-f*(f-1)*(f-2)/6)*table[n-1] + ((f+1)*(f-1)*(f-2)/2)*table[n] 
				       -((f+1)*f*(f-2)/2)*table[n+1] + ((f+1)*f*(f-1)/6)*table[n+2];
		return (int)y;	
	}
	
	public void setFrequency(double frequency) {
		this.frequency = frequency;
	}
	
	public void setSampleAt(int index, int value) {
		table[index+1] = value;
		
		if( index==tableLength)
			table[0] = value;		
		else if( index==0 )
			table[tableLength+1]=value;
		else if( index==1)
			table[tableLength+2]=value;
	}
	
	public void print() {
		for(int i=0; i<tableLength; i++) {
			System.out.println( table[i] );
		}
	}
	
	private void addPartial(int k) {
		for(int i=0; i<tableLength+2; i++) {
			table[i+1] += (1000)*Math.sin(2*Math.PI*k*i/tableLength);
		}
		table[0]=table[tableLength];
	}
}
